/**
 * 
 */
package vn.support.connection;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;
import vn.support.connection.response.processor.ResponseDecode;
import vn.support.connection.response.processor.ResponseProcessor;
import vn.support.core.dto.DataObject;
import vn.support.system.SystemProperties;

/**
 * Implement of {@link Connection}
 * Su dung mot thread moi de thuc hien chuc nang connection!
 * @author nttuyen
 * @version 0.0.1
 */
public class RequestConnection implements Connection {
	private static final Logger log = Logger.getLogger(RequestConnection.class);

	public static final String MODULE = "livesupport";

    @Override
	public void execute(final DataObject data) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                String action = data.getName().toLowerCase();
                ResponseProcessor processor = data.get(RESPONSE_PROCESSOR);

                if(processor == null) {
                    log.debug("Processor is null");
                }

                StringBuilder uri = new StringBuilder();
                uri.append(SystemProperties.get(SystemProperties.URL));
                uri.append("?_m=");
                uri.append(MODULE);
                uri.append("&_a=");
                uri.append(action);

                //LOGIN, LOGOUT
                if (action.equalsIgnoreCase(LOGIN_ACTION)) {
                    uri.append("&_ca=" + LOGIN_ACTION);
                } else if (action.equalsIgnoreCase(LOGOUT_ACTION)) {
                    uri.append("&_ca=" + LOGOUT_ACTION);
                }
                Map<String, Object> attributes = data.getAttributes();
                for (String key : attributes.keySet()) {
                    uri.append("&");
                    uri.append(key);
                    uri.append("=");
                    uri.append(attributes.get(key));
                }
                log.debug("URL: " + uri.toString());
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost(uri.toString());
                client.getParams().setParameter("http.protocol.content-charset", "UTF-8");
                try {
                    HttpResponse res = client.execute(post);
                    HttpEntity entity = res.getEntity();
                    if (entity != null) {
                        StringBuilder response = new StringBuilder();
                        BufferedReader input = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                        String line = null;
                        while ((line = input.readLine()) != null) {
                            response.append(line);
                            response.append("\n");
                        }
                        log.debug("Response: " + response.toString());

                        DataObject responseData = new DataObject(DTO_RESPONSE_NAME);
                        responseData.set(DTO_RESPONSE_ACTION, data.getName());
                        responseData.set(DTO_REQUEST_DATA, data);

                        // Process Response
                        int start = 0;
                        int index = response.indexOf(";");
                        responseData.set(DTO_RESPONSE_COMPRESSION, response.substring(start, index));
                        response = new StringBuilder(response.substring(index + 1));

                        index = response.indexOf(";");
                        responseData.set(DTO_RESPONSE_MD5_COMPRESSION, response.substring(start, index));
                        response = new StringBuilder(response.substring(index + 1));

                        index = response.indexOf(";");
                        responseData.set(DTO_RESPONSE_MD5_UNCOMPRESSION, response.substring(start, index));
                        response = new StringBuilder(response.substring(index + 1));

                        index = response.indexOf(";");
                        responseData.set(DTO_RESPONSE_SIZE_COMPRESSION, response.substring(start, index));
                        response = new StringBuilder(response.substring(index + 1));

                        index = response.indexOf(";");
                        responseData.set(DTO_RESPONSE_SIZE_UNCOMPRESSION, response.substring(start, index));
                        response = new StringBuilder(response.substring(index + 1));

                        responseData.set(DTO_RESPONSE_DATA, response.toString().trim());

                        ResponseProcessor decode = new ResponseDecode();
                        responseData = decode.process(responseData);

                        if(processor != null) {
                            processor.process(responseData);
                        }
                    }
                } catch (Exception e) {
                    log.error("Request exception", e);
                    DataObject exception = new DataObject(action);
                    exception.set(Connection.DTO_RESPONSE_EXCEPTION, e);
                    if(processor != null) {
                        processor.process(exception);
                    }
                }
            }
        });
        t.setName(data.getName());
        t.start();
	}

}
